package com.author.surface;

import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.font.FontRenderContext;
import javax.swing.JToggleButton;
import javax.swing.border.BevelBorder;

import com.author.document.style.StyleChangeNotify;

public class AlignActionButtonGroup {
	/**
	 * Align action will have four buttons corresponding to four alignment
	 * actions - Left, Center, Right and Justify
	 */
	private final static JToggleButton	LEFT_ALIGN		= new AlignActionButtonGroup.AlignLeft();
	private final static JToggleButton	CENTER_ALIGN	= new AlignActionButtonGroup.AlignCenter();
	private final static JToggleButton	RIGHT_ALIGN		= new AlignActionButtonGroup.AlignRight();
	private final static JToggleButton	JUSTIFY_ALIGN	= new AlignActionButtonGroup.AlignJustify();

	public static AlignLeft getAlignLeft() {
		return (AlignLeft) LEFT_ALIGN;
	}

	public static AlignCenter getAlignCenter() {
		return (AlignCenter) CENTER_ALIGN;
	}

	public static AlignRight getAlignRight() {
		return (AlignRight) RIGHT_ALIGN;
	}

	public static AlignJustify getAlignJustify() {
		return (AlignJustify) JUSTIFY_ALIGN;
	}

	protected static class AlignLeft extends JToggleButton implements
			ActionListener {
		/** X and Y coordinates of the visible lines */
		private int					x1, x2;
		private int					y1, y2;

		/** Display properties of the button */
		private static final int	ALIGN_BUTTON_WIDTH		= 32;
		private static final int	ALIGN_BUTTON_HEIGHT		= 32;
		private static final int	ALIGN_BUTTON_FONT_SIZE	= 24;

		/** Font used on the alignment button */
		private Font				alignLeftButtonFont		= new Font(
																	fontName,
																	Font.PLAIN,
																	ALIGN_BUTTON_FONT_SIZE);
		private static final String	fontName				= "Monospaced";

		/** Current state of the Left alignment button */
		private boolean				currentState			= false;

		public AlignLeft() {
			super();
			// Set size of the LEFT ALIGN button
			setSize(new Dimension(ALIGN_BUTTON_WIDTH, ALIGN_BUTTON_HEIGHT));
			setPreferredSize(getSize());
			setEnabled(true);

			// Set border of the LEFT ALIGN button
			setBorder(new BevelBorder(BevelBorder.LOWERED));
			setBorderPainted(false);

			// Set visible properties
			setFont(alignLeftButtonFont);
			setToolTipText("Align Left");
			setFocusable(false);
			setVisible(true);

			// Make the LEFT ALIGN button respond to user click action
			addActionListener(this);
		}

		/**
		 * This method will be executed in response to the message from UI
		 * updater which will request the alignment button to check if it needs
		 * to update its state based on the current caret position
		 */
		public void setAlignmentLeft(boolean value) {
			if (value == true) {
				if (!isSelected()) {
					setSelected(true);
					currentState = true;
				}
			}

			if (value == false) {
				if (isSelected()) {
					setSelected(false);
					currentState = false;
				}
			}
		}

		public void paint(Graphics g) {
			super.paint(g);
			Graphics2D g2d = (Graphics2D) g;
			g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
					RenderingHints.VALUE_ANTIALIAS_ON);

			// draw lines indicating that the button is to be used for left
			// alignment
			x1 = 5;
			y1 = 5;
			x2 = 25;
			y2 = 5;
			g2d.drawLine(x1, y1, x2, y2);

			x1 = 5;
			y1 = 10;
			x2 = 15;
			y2 = 10;
			g2d.drawLine(x1, y1, x2, y2);

			x1 = 5;
			y1 = 15;
			x2 = 25;
			y2 = 15;
			g2d.drawLine(x1, y1, x2, y2);

			x1 = 5;
			y1 = 20;
			x2 = 15;
			y2 = 20;
			g2d.drawLine(x1, y1, x2, y2);

			x1 = 5;
			y1 = 25;
			x2 = 25;
			y2 = 25;
			g2d.drawLine(x1, y1, x2, y2);
		}

		@Override
		public void actionPerformed(ActionEvent event) {
			if (event == null) return;
			if (event.getSource() instanceof JToggleButton) {
				JToggleButton button = (JToggleButton) event.getSource();
				StyleChangeNotify styleChangeNotify = StyleChangeNotify
						.getStyleChangeNotify();

				/*
				 * Get the status of the other alignment buttons, as only one
				 * can be active at a time. When any one is chosen, others are
				 * turned off immediately.
				 */
				if (button.isSelected()) {
					JToggleButton button1 = AlignActionButtonGroup.CENTER_ALIGN;
					JToggleButton button2 = AlignActionButtonGroup.RIGHT_ALIGN;
					JToggleButton button3 = AlignActionButtonGroup.JUSTIFY_ALIGN;

					if (button1.isSelected()) {
						styleChangeNotify.setAlignmentCenter(true, false);
						button1.setSelected(false);
					}

					if (button2.isSelected()) {
						styleChangeNotify.setAlignmentRight(true, false);
						button2.setSelected(false);
					}

					if (button3.isSelected()) {
						styleChangeNotify.setAlignmentJustify(true, false);
						button3.setSelected(false);
					}

					// make changes as per user action
					currentState = true;
					styleChangeNotify.setAlignmentLeft(false, true);
				} else {
					currentState = false;
					styleChangeNotify.setAlignmentLeft(true, false);
				}
			}
		}
	}

	protected static class AlignCenter extends JToggleButton implements
			ActionListener {
		/** X and Y coordinates of the visible lines */
		private int					x1, x2;
		private int					y1, y2;

		/** Display properties of the button */
		private static final int	ALIGN_BUTTON_WIDTH		= 32;
		private static final int	ALIGN_BUTTON_HEIGHT		= 32;
		private static final int	ALIGN_BUTTON_FONT_SIZE	= 24;

		/** Font used on the align button */
		private Font				alignCenterButtonFont	= new Font(
																	fontName,
																	Font.PLAIN,
																	ALIGN_BUTTON_FONT_SIZE);
		private static final String	fontName				= "Monospaced";

		/** Current state of the Center alignment button */
		private boolean				currentState			= false;

		public AlignCenter() {
			super();
			// Set size of the CENTER ALIGN button
			setSize(new Dimension(ALIGN_BUTTON_WIDTH, ALIGN_BUTTON_HEIGHT));
			setPreferredSize(getSize());
			setEnabled(true);

			// Set border of the CENTER ALIGN button
			setBorder(new BevelBorder(BevelBorder.LOWERED));
			setBorderPainted(false);

			// Set visible properties
			setFont(alignCenterButtonFont);
			setToolTipText("Align Center");
			setFocusable(false);
			setVisible(true);

			// Make the CENTER ALIGN button respond to user click action
			addActionListener(this);
		}

		/**
		 * This method will be executed in response to the message from UI
		 * updater which will request the alignment button to check if it needs
		 * to update its state based on the current caret position
		 */
		public void setAlignmentCenter(boolean value) {
			if (value == true) {
				if (!isSelected()) {
					setSelected(true);
					currentState = true;
				}
			}

			if (value == false) {
				if (isSelected()) {
					setSelected(false);
					currentState = false;
				}
			}
		}

		public void paint(Graphics g) {
			super.paint(g);
			Graphics2D g2d = (Graphics2D) g;
			g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
					RenderingHints.VALUE_ANTIALIAS_ON);

			// draw lines indicating that the button is to be used for center
			// alignment
			x1 = 5;
			y1 = 5;
			x2 = 25;
			y2 = 5;
			g2d.drawLine(x1, y1, x2, y2);

			x1 = 8;
			y1 = 10;
			x2 = 22;
			y2 = 10;
			g2d.drawLine(x1, y1, x2, y2);

			x1 = 5;
			y1 = 15;
			x2 = 25;
			y2 = 15;
			g2d.drawLine(x1, y1, x2, y2);

			x1 = 8;
			y1 = 20;
			x2 = 22;
			y2 = 20;
			g2d.drawLine(x1, y1, x2, y2);

			x1 = 5;
			y1 = 25;
			x2 = 25;
			y2 = 25;
			g2d.drawLine(x1, y1, x2, y2);
		}

		@Override
		public void actionPerformed(ActionEvent event) {
			if (event == null) return;
			if (event.getSource() instanceof JToggleButton) {
				JToggleButton button = (JToggleButton) event.getSource();
				StyleChangeNotify styleChangeNotify = StyleChangeNotify
						.getStyleChangeNotify();

				/*
				 * Get the status of the other alignment buttons, as only one
				 * can be active at a time. When any one is chosen, others are
				 * turned off immediately.
				 */
				if (button.isSelected()) {
					JToggleButton button1 = AlignActionButtonGroup.LEFT_ALIGN;
					JToggleButton button2 = AlignActionButtonGroup.RIGHT_ALIGN;
					JToggleButton button3 = AlignActionButtonGroup.JUSTIFY_ALIGN;

					if (button1.isSelected()) {
						styleChangeNotify.setAlignmentLeft(true, false);
						button1.setSelected(false);
					}

					if (button2.isSelected()) {
						styleChangeNotify.setAlignmentRight(true, false);
						button2.setSelected(false);
					}

					if (button3.isSelected()) {
						styleChangeNotify.setAlignmentJustify(true, false);
						button3.setSelected(false);
					}

					// make changes as per user action
					currentState = true;
					styleChangeNotify.setAlignmentCenter(false, true);
				} else {
					currentState = false;
					styleChangeNotify.setAlignmentCenter(true, false);
				}
			}
		}
	}

	protected static class AlignRight extends JToggleButton implements
			ActionListener {
		/** X and Y coordinates of the visible lines */
		private int					x1, x2;
		private int					y1, y2;

		/** Display properties of the button */
		private static final int	ALIGN_BUTTON_WIDTH		= 32;
		private static final int	ALIGN_BUTTON_HEIGHT		= 32;
		private static final int	ALIGN_BUTTON_FONT_SIZE	= 24;

		/** Font used on the align button */
		private Font				alignRightButtonFont	= new Font(
																	fontName,
																	Font.PLAIN,
																	ALIGN_BUTTON_FONT_SIZE);
		private static final String	fontName				= "Monospaced";

		/** Current state of the Right alignment button */
		private boolean				currentState			= false;

		public AlignRight() {
			super();
			// Set size of the RIGHT ALIGN button
			setSize(new Dimension(ALIGN_BUTTON_WIDTH, ALIGN_BUTTON_HEIGHT));
			setPreferredSize(getSize());
			setEnabled(true);

			// Set border of the RIGHT ALIGN button
			setBorder(new BevelBorder(BevelBorder.LOWERED));
			setBorderPainted(false);

			// Set visible properties
			setFont(alignRightButtonFont);
			setToolTipText("Align Right");
			setFocusable(false);
			setVisible(true);

			// Make the RIGHT ALIGN button respond to user click action
			addActionListener(this);
		}

		/**
		 * This method will be executed in response to the message from UI
		 * updater which will request the alignment button to check if it needs
		 * to update its state based on the current caret position
		 */
		public void setAlignmentRight(boolean value) {
			if (value == true) {
				if (!isSelected()) {
					setSelected(true);
					currentState = true;
				}
			}

			if (value == false) {
				if (isSelected()) {
					setSelected(false);
					currentState = false;
				}
			}
		}

		public void paint(Graphics g) {
			super.paint(g);
			Graphics2D g2d = (Graphics2D) g;
			g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
					RenderingHints.VALUE_ANTIALIAS_ON);

			// draw lines indicating that the button is to be used for right
			// alignment
			x1 = 5;
			y1 = 5;
			x2 = 25;
			y2 = 5;
			g2d.drawLine(x1, y1, x2, y2);

			x1 = 15;
			y1 = 10;
			x2 = 25;
			y2 = 10;
			g2d.drawLine(x1, y1, x2, y2);

			x1 = 5;
			y1 = 15;
			x2 = 25;
			y2 = 15;
			g2d.drawLine(x1, y1, x2, y2);

			x1 = 15;
			y1 = 20;
			x2 = 25;
			y2 = 20;
			g2d.drawLine(x1, y1, x2, y2);

			x1 = 5;
			y1 = 25;
			x2 = 25;
			y2 = 25;
			g2d.drawLine(x1, y1, x2, y2);
		}

		@Override
		public void actionPerformed(ActionEvent event) {
			if (event == null) return;
			if (event.getSource() instanceof JToggleButton) {
				JToggleButton button = (JToggleButton) event.getSource();
				StyleChangeNotify styleChangeNotify = StyleChangeNotify
						.getStyleChangeNotify();

				/*
				 * Get the status of the other alignment buttons, as only one
				 * can be active at a time. When any one is chosen, others are
				 * turned off immediately.
				 */
				if (button.isSelected()) {
					JToggleButton button1 = AlignActionButtonGroup.LEFT_ALIGN;
					JToggleButton button2 = AlignActionButtonGroup.CENTER_ALIGN;
					JToggleButton button3 = AlignActionButtonGroup.JUSTIFY_ALIGN;

					if (button1.isSelected()) {
						styleChangeNotify.setAlignmentLeft(true, false);
						button1.setSelected(false);
					}

					if (button2.isSelected()) {
						styleChangeNotify.setAlignmentCenter(true, false);
						button2.setSelected(false);
					}

					if (button3.isSelected()) {
						styleChangeNotify.setAlignmentJustify(true, false);
						button3.setSelected(false);
					}

					// make changes as per user action
					currentState = true;
					styleChangeNotify.setAlignmentRight(false, true);
				} else {
					currentState = false;
					styleChangeNotify.setAlignmentRight(true, false);
				}
			}
		}
	}

	protected static class AlignJustify extends JToggleButton implements
			ActionListener {
		/** X and Y coordinates of the visible lines */
		private int					x1, x2;
		private int					y1, y2;

		/** Display properties of the button */
		private static final int	ALIGN_BUTTON_WIDTH		= 32;
		private static final int	ALIGN_BUTTON_HEIGHT		= 32;
		private static final int	ALIGN_BUTTON_FONT_SIZE	= 24;

		/** Font used on the align button */
		private Font				alignJustifyButtonFont	= new Font(
																	fontName,
																	Font.PLAIN,
																	ALIGN_BUTTON_FONT_SIZE);
		private static final String	fontName				= "Monospaced";

		/** Current state of the Justify alignment button */
		private boolean				currentState			= false;

		public AlignJustify() {
			super();
			// Set size of the JUSTIFY ALIGN button
			setSize(new Dimension(ALIGN_BUTTON_WIDTH, ALIGN_BUTTON_HEIGHT));
			setPreferredSize(getSize());
			setEnabled(true);

			// Set border of the JUSTIFY ALIGN button
			setBorder(new BevelBorder(BevelBorder.LOWERED));
			setBorderPainted(false);

			// Set visible properties
			setFont(alignJustifyButtonFont);
			setToolTipText("Align Justify");
			setFocusable(false);
			setVisible(true);

			// Make the JUSTIFY ALIGN button respond to user click action
			addActionListener(this);
		}

		/**
		 * This method will be executed in response to the message from UI
		 * updater which will request the alignment button to check if it needs
		 * to update its state based on the current caret position
		 */
		public void setAlignmentJustify(boolean value) {
			if (value == true) {
				if (!isSelected()) {
					setSelected(true);
					currentState = true;
				}
			}

			if (value == false) {
				if (isSelected()) {
					setSelected(false);
					currentState = false;
				}
			}
		}

		public void paint(Graphics g) {
			super.paint(g);
			Graphics2D g2d = (Graphics2D) g;
			g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
					RenderingHints.VALUE_ANTIALIAS_ON);

			// draw lines indicating that the button is to be used for justify
			// alignment
			x1 = 5;
			y1 = 5;
			x2 = 25;
			y2 = 5;
			g2d.drawLine(x1, y1, x2, y2);

			x1 = 5;
			y1 = 10;
			x2 = 25;
			y2 = 10;
			g2d.drawLine(x1, y1, x2, y2);

			x1 = 5;
			y1 = 15;
			x2 = 25;
			y2 = 15;
			g2d.drawLine(x1, y1, x2, y2);

			x1 = 5;
			y1 = 20;
			x2 = 25;
			y2 = 20;
			g2d.drawLine(x1, y1, x2, y2);

			x1 = 5;
			y1 = 25;
			x2 = 25;
			y2 = 25;
			g2d.drawLine(x1, y1, x2, y2);
		}

		@Override
		public void actionPerformed(ActionEvent event) {
			if (event == null) return;
			if (event.getSource() instanceof JToggleButton) {
				JToggleButton button = (JToggleButton) event.getSource();
				StyleChangeNotify styleChangeNotify = StyleChangeNotify
						.getStyleChangeNotify();

				/*
				 * Get the status of the other alignment buttons, as only one
				 * can be active at a time. When any one is chosen, others are
				 * turned off immediately.
				 */
				if (button.isSelected()) {
					JToggleButton button1 = AlignActionButtonGroup.LEFT_ALIGN;
					JToggleButton button2 = AlignActionButtonGroup.CENTER_ALIGN;
					JToggleButton button3 = AlignActionButtonGroup.RIGHT_ALIGN;

					if (button1.isSelected()) {
						styleChangeNotify.setAlignmentLeft(true, false);
						button1.setSelected(false);
					}

					if (button2.isSelected()) {
						styleChangeNotify.setAlignmentCenter(true, false);
						button2.setSelected(false);
					}

					if (button3.isSelected()) {
						styleChangeNotify.setAlignmentRight(true, false);
						button3.setSelected(false);
					}

					// make changes as per user action
					currentState = true;
					styleChangeNotify.setAlignmentJustify(false, true);
				} else {
					currentState = false;
					styleChangeNotify.setAlignmentJustify(true, false);
				}
			}
		}
	}

}
